#include "include.h"
#include "ab_mate_profile.h"

#if AB_MATE_APP_EN && GFPS_EN

#define ADV_CID_POS     (2)
#define ADV_VID_POS     (4)
#define ADV_MAC_POS     (7)
#define ADV_FMASK_POS   (13)
#define ADV_BID_POS     (14)

#define SPP_TX_BUF_INX      4
#define SPP_TX_BUF_LEN      128     //max=512
#define SPP_POOL_SIZE       (SPP_TX_BUF_LEN + sizeof(struct txbuf_tag)) * SPP_TX_BUF_INX

static u8 *p_adv_data;
static u8 adv_data_len AT(.ab_mate.buf);
static u8 *p_scan_data;
static u8 scan_data_len AT(.ab_mate.buf);

AT(.ble_buf.stack.spp)
uint8_t spp_custom1_tx_pool[SPP_POOL_SIZE];

const uint8_t sdp_gfps_spp_service_record[] = {
    0x36, 0x00, 0x62, 0x09, 0x00, 0x00, 0x0a, 0x50, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x36, 0x00,
    0x11, 0x1C, 0xdf, 0x21, 0xfe, 0x2c, 0x25, 0x15, 0x4f, 0xdb, 0x88, 0x86, 0xf1, 0x2c, 0x4d, 0x67,
    0x92, 0x7c, 0x09, 0x00, 0x04, 0x36, 0x00, 0x0e, 0x36, 0x00, 0x03, 0x19, 0x01, 0x00, 0x36, 0x00,
    0x05, 0x19, 0x00, 0x03, 0x08, 0x05, 0x09, 0x00, 0x05, 0x36, 0x00, 0x03, 0x19, 0x10, 0x02, 0x09,
    0x00, 0x06, 0x36, 0x00, 0x09, 0x09, 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01, 0x00, 0x09, 0x00,
    0x09, 0x36, 0x00, 0x09, 0x36, 0x00, 0x06, 0x19, 0x11, 0x01, 0x09, 0x11, 0x02, 0x09, 0x01, 0x00,
    0x25, 0x03, 0x53, 0x50, 0x50,
};

void spp_custom1_txpkt_init(void)
{
    txpkt_init(&spp_custom1_tx, spp_custom1_tx_pool, SPP_TX_BUF_INX, SPP_TX_BUF_LEN);
    spp_custom1_tx.send_kick = spp_send_kick;
}


//BLE PROFILE DATA
const uint8_t profile_data[] =
{
    //ab_mate
    // 0x0001 PRIMARY_SERVICE-FDB3
    0x0a, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x28, 0xb3, 0xfd,
    // 0x0002 CHARACTERISTIC-FF18-READ | NOTIFY
    0x0d, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x28, 0x12, 0x03, 0x00, 0x18, 0xff,
    // 0x0003 VALUE-FF18-READ | NOTIFY-''
    // READ_ANYBODY
    0x08, 0x00, 0x02, 0x00, 0x03, 0x00, 0x18, 0xff,
    // 0x0004 CLIENT_CHARACTERISTIC_CONFIGURATION
    // READ_ANYBODY, WRITE_ANYBODY
    0x0a, 0x00, 0x0a, 0x01, 0x04, 0x00, 0x02, 0x29, 0x00, 0x00,
    // 0x0005 CHARACTERISTIC-FF16-READ | WRITE | DYNAMIC
    0x0d, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x28, 0x0a, 0x06, 0x00, 0x16, 0xff,
    // 0x0006 VALUE-FF16-READ | WRITE | DYNAMIC-''
    // READ_ANYBODY, WRITE_ANYBODY
    0x08, 0x00, 0x0a, 0x01, 0x06, 0x00, 0x16, 0xff,
    // 0x0007 CHARACTERISTIC-FF17-WRITE | WRITE_WITHOUT_RESPONSE | DYNAMIC
    0x0d, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x28, 0x0c, 0x08, 0x00, 0x17, 0xff,
    // 0x0008 VALUE-FF17-WRITE | WRITE_WITHOUT_RESPONSE | DYNAMIC-''
    // WRITE_ANYBODY
    0x08, 0x00, 0x0c, 0x01, 0x08, 0x00, 0x17, 0xff,

    //gfps
    // 0x0001 PRIMARY_SERVICE-FE2C
    0x0a, 0x00, 0x02, 0x00, 0x21, 0x00, 0x00, 0x28, 0x2c, 0xfe,

    // 0x0002 CHARACTERISTIC-FE2C1233-8366-4814-8EB0-01DE32100BEA-READ | DYNAMIC
    0x1b, 0x00, 0x02, 0x00, 0x22, 0x00, 0x03, 0x28, 0x02, 0x23, 0x00, 0xea, 0x0b, 0x10, 0x32, 0xde, 0x01, 0xb0, 0x8e, 0x14, 0x48, 0x66, 0x83, 0x33, 0x12, 0x2c, 0xfe,
    // 0x0003 VALUE-FE2C1233-8366-4814-8EB0-01DE32100BEA-READ | DYNAMIC-''
    // READ_ANYBODY
    0x16, 0x00, 0x02, 0x03, 0x23, 0x00, 0xea, 0x0b, 0x10, 0x32, 0xde, 0x01, 0xb0, 0x8e, 0x14, 0x48, 0x66, 0x83, 0x33, 0x12, 0x2c, 0xfe,

    // 0x0004 CHARACTERISTIC-FE2C1234-8366-4814-8EB0-01DE32100BEA-WRITE | NOTIFY | DYNAMIC
    0x1b, 0x00, 0x02, 0x00, 0x24, 0x00, 0x03, 0x28, 0x18, 0x25, 0x00, 0xea, 0x0b, 0x10, 0x32, 0xde, 0x01, 0xb0, 0x8e, 0x14, 0x48, 0x66, 0x83, 0x34, 0x12, 0x2c, 0xfe,
    // 0x0005 VALUE-FE2C1234-8366-4814-8EB0-01DE32100BEA-WRITE | NOTIFY | DYNAMIC-''
    // WRITE_ANYBODY
    0x16, 0x00, 0x08, 0x03, 0x25, 0x00, 0xea, 0x0b, 0x10, 0x32, 0xde, 0x01, 0xb0, 0x8e, 0x14, 0x48, 0x66, 0x83, 0x34, 0x12, 0x2c, 0xfe,
    // 0x0006 CLIENT_CHARACTERISTIC_CONFIGURATION
    // READ_ANYBODY, WRITE_ANYBODY
    0x0a, 0x00, 0x0a, 0x01, 0x26, 0x00, 0x02, 0x29, 0x00, 0x00,

    // 0x0007 CHARACTERISTIC-FE2C1235-8366-4814-8EB0-01DE32100BEA-WRITE | NOTIFY | DYNAMIC
    0x1b, 0x00, 0x02, 0x00, 0x27, 0x00, 0x03, 0x28, 0x18, 0x28, 0x00, 0xea, 0x0b, 0x10, 0x32, 0xde, 0x01, 0xb0, 0x8e, 0x14, 0x48, 0x66, 0x83, 0x35, 0x12, 0x2c, 0xfe,
    // 0x0008 VALUE-FE2C1235-8366-4814-8EB0-01DE32100BEA-WRITE | NOTIFY | DYNAMIC-''
    // WRITE_ANYBODY
    0x16, 0x00, 0x08, 0x03, 0x28, 0x00, 0xea, 0x0b, 0x10, 0x32, 0xde, 0x01, 0xb0, 0x8e, 0x14, 0x48, 0x66, 0x83, 0x35, 0x12, 0x2c, 0xfe,
    // 0x0009 CLIENT_CHARACTERISTIC_CONFIGURATION
    // READ_ANYBODY, WRITE_ANYBODY
    0x0a, 0x00, 0x0a, 0x01, 0x29, 0x00, 0x02, 0x29, 0x00, 0x00,

    // 0x000a CHARACTERISTIC-FE2C1236-8366-4814-8EB0-01DE32100BEA-WRITE | DYNAMIC
    0x1b, 0x00, 0x02, 0x00, 0x2a, 0x00, 0x03, 0x28, 0x08, 0x2b, 0x00, 0xea, 0x0b, 0x10, 0x32, 0xde, 0x01, 0xb0, 0x8e, 0x14, 0x48, 0x66, 0x83, 0x36, 0x12, 0x2c, 0xfe,
    // 0x000b VALUE-FE2C1236-8366-4814-8EB0-01DE32100BEA-WRITE | DYNAMIC-''
    // WRITE_ANYBODY
    0x16, 0x00, 0x08, 0x03, 0x2b, 0x00, 0xea, 0x0b, 0x10, 0x32, 0xde, 0x01, 0xb0, 0x8e, 0x14, 0x48, 0x66, 0x83, 0x36, 0x12, 0x2c, 0xfe,

    // 0x000c CHARACTERISTIC-FE2C1237-8366-4814-8EB0-01DE32100BEA-WRITE | NOTIFY | DYNAMIC
    0x1b, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x03, 0x28, 0x18, 0x2d, 0x00, 0xea, 0x0b, 0x10, 0x32, 0xde, 0x01, 0xb0, 0x8e, 0x14, 0x48, 0x66, 0x83, 0x37, 0x12, 0x2c, 0xfe,
    // 0x000d VALUE-FE2C1237-8366-4814-8EB0-01DE32100BEA-WRITE | NOTIFY | DYNAMIC-''
    // WRITE_ANYBODY
    0x16, 0x00, 0x08, 0x03, 0x2d, 0x00, 0xea, 0x0b, 0x10, 0x32, 0xde, 0x01, 0xb0, 0x8e, 0x14, 0x48, 0x66, 0x83, 0x37, 0x12, 0x2c, 0xfe,
    // 0x000e CLIENT_CHARACTERISTIC_CONFIGURATION
    // READ_ANYBODY, WRITE_ANYBODY
    0x0a, 0x00, 0x0a, 0x01, 0x2e, 0x00, 0x02, 0x29, 0x00, 0x00,

#if ENABLE_FIRMWARE_REVISION
    // 0x000f PRIMARY_SERVICE-280A
    0x0a, 0x00, 0x02, 0x00, 0x1e, 0x00, 0x00, 0x28, 0x0a, 0x28,
    // 0x0010 CHARACTERISTIC-2A26-READ | DYNAMIC
    0x0d, 0x00, 0x02, 0x00, 0x1f, 0x00, 0x03, 0x28, 0x02, 0x21, 0x00, 0x26, 0x2a,
    // 0x0011 VALUE-2A26-READ | DYNAMIC-''
    // READ_ANYBODY
    0x08, 0x00, 0x02, 0x01, 0x20, 0x00, 0x26, 0x2a,
#endif // ENABLE_FIRMWARE_REVISION

 	// END
    0x00, 0x00,
}; // total size 99 bytes

const u8 *ble_get_profile_data(void)
{
    //printf("%s\n",__func__);
    return profile_data;
}

static const uint8_t adv_data_const[] = {
    // Flags general discoverable, BR/EDR not supported
    0x02, 0x01, 0x02,
    // GFPS, Tx Power, -20dBm
    0x02, 0x0A, 0xF5,
};

static const uint8_t scan_data_const[] = {
                //CID      VID   PID        MAC                            FMASK  BID
    0x10, 0xff, 0x42,0x06, 0x01, 0x01,0x00, 0x00,0x00,0x00,0x00,0x00,0x00, 0x00,  0x00,0x00,0x00,
    //Name
    0x04, 0x09, 'B','L','E',
};

u32 ble_get_scan_data(u8 *scan_buf, u32 buf_size)
{
    u8 edr_addr[6];
    u32 bid = AB_MATE_BID;

    p_scan_data = scan_buf;

    memset(scan_buf, 0, buf_size);
    u32 data_len = sizeof(scan_data_const);
    memcpy(scan_buf, scan_data_const, data_len);

    scan_buf[ADV_VID_POS] = AB_MATE_VID;

    bt_get_local_bd_addr(edr_addr);

    //广播包协议从版本1之后，经典蓝牙地址都做个简单的加密操作，不直接暴露地址
    if(AB_MATE_VID > 1){
        for(u8 i = 0; i < 6; i++){
            edr_addr[i] ^= 0xAD;
        }
    }

    memcpy(&scan_buf[ADV_MAC_POS], edr_addr, 6);

    memcpy(&scan_buf[ADV_BID_POS], &bid, 3);

#if LE_SM_SC_EN
    scan_buf[ADV_FMASK_POS] |= BIT(1);
#endif

#ifdef AB_MATE_SPP_UUID
    scan_buf[ADV_FMASK_POS] |= BIT(4);
#endif

    //读取BLE配置的蓝牙名称
    int len;
    len = strlen(xcfg_cb.le_name);
    len = len > 12 ? 12 : len;

    if (len > 0) {
        memcpy(&scan_buf[19], xcfg_cb.le_name, len);
        data_len = 19 + len;
        scan_buf[17] = len + 1;
    }

    scan_data_len = data_len;

    return data_len;
}

u32 ble_get_adv_data(u8 *adv_buf, u32 buf_size)
{
    p_adv_data = adv_buf;

    memset(adv_buf, 0, buf_size);

    u32 data_len = sizeof(adv_data_const);
    memcpy(adv_buf, adv_data_const, data_len);

    adv_data_len = data_len;

    return data_len;
}

void ble_adv_data_update_byte(u8 pos, u8* val, u8 len, u8 proc)
{
    if(p_adv_data){
        memcpy(&p_adv_data[pos], val, len);

        if(proc){
            ble_set_adv_data(p_adv_data, adv_data_len);
        }
    }
}

void ble_adv_data_update_bit(u8 pos, u8 bit, u8 val, u8 len, u8 proc)
{
    if(p_adv_data){
        for(u8 i= 0; i< len; i++){
            p_adv_data[pos] &= ~(1 << (bit + i));
        }

        p_adv_data[pos] |= (val << bit);

        if(proc){
            ble_set_adv_data(p_adv_data, adv_data_len);
        }
    }
}

void ble_scan_rsp_update_byte(u8 pos, u8* val, u8 len, u8 proc)
{
    if(p_scan_data){
        memcpy(&p_scan_data[pos], val, len);

        if(proc){
            ble_set_scan_rsp_data(p_scan_data, scan_data_len);
        }
    }
}

void ble_scan_rsp_update_bit(u8 pos, u8 bit, u8 val, u8 len, u8 proc)
{
    if(p_scan_data){
        for(u8 i= 0; i< len; i++){
            p_scan_data[pos] &= ~(1 << (bit + i));
        }

        p_scan_data[pos] |= (val << bit);

        if(proc){
            ble_set_scan_rsp_data(p_scan_data, scan_data_len);
        }
    }
}

void ab_mate_update_ble_adv_fmsk(u8 bit, u8 val, u8 len, u8 proc)
{
    ble_scan_rsp_update_bit(ADV_FMASK_POS, bit, val, len, proc);
}

void ab_mate_update_ble_adv_bt_sta(u8 val, u8 proc)
{
    ab_mate_update_ble_adv_fmsk(2, val, 2, proc);
}

void ab_mate_disable_adv_for_spp_connect(void)
{
    u8 cid[2] = {0xFF, 0xFF};

    ble_scan_rsp_update_byte(ADV_CID_POS, cid, 2, 1);
}

void ab_mate_enable_adv_for_spp_disconnect(void)
{
    u8 cid[2] = {0x42, 0x06};

    ble_scan_rsp_update_byte(ADV_CID_POS, cid, 2, 1);
}

#endif
